Chapter 20: Pandas
From book
Python Programming (Problem solving, Packages and Libraries)
Published by McGraw Hill Education (India) Private limited.
By:

  • Anurag Gupta
  • G. P. Biswas

Note the following:-

  1. This html document is meant as an accompaniment to Chapter 20 Pandas .
  2. The document contains scripts executed on IDLE as well as on Jupyter notebook.
  3. The scripts executed on Jupyter can be directly copied and run into a Jupyter notebook or some other IDE (Like Pycharm or Eclipse with PyDev or Visual studio).
  4. However the scripts on IDLE also contain the >>> symbol and therefore cannot be directly executed. If you want to execute them on IDLE or Jupyter, you need to manually remove the >>> symbol.
  5. Wherever needed some background material from the book is also included to help you better understand the scripts
  6. The topic numbers given on each paragraph match the topic numbers of the book, so you can easily identify the topics and corresponding scripts.
  7. In some of the scripts, the file paths given are that of the author's computer. You need to replace them with file paths of your own computer.
  8. At some places, to improve readability, page numbers of the book are indicated in green font like:- See Page 181 of the book
  9. This document was first created as a Jupyter Notebook as combination of Markdown and code cells (extension .ipynb) and then downloaded as html. If someone wants to "modify" or "extend' this document, you may ask for the original .ipynb file by sending me an e-mail at:- 999.anuraggupta@gmail.com
  10. A seperate html document has been created to provide the code for the 20.7. Assignment/Project 20.7.1. Project 1. This was done because the exercise was long.

20.2. Basics of pandas
20.2.1. Series
The following script shows how to create two Series objects s1 and s2 on Jupyter notebook:
This script is available on page 515 of the book

In [1]:
import pandas as pd
s1 = pd.Series([1, 'cat', (2,3)])
s2 = pd.Series(['Ant', 'bat', 'cat'], index = ['A', 'B', 'C'])
print('s1->', s1)
print('s2->', s2)
s1-> 0         1
1       cat
2    (2, 3)
dtype: object
s2-> A    Ant
B    bat
C    cat
dtype: object

20.2.2. DataFrame
The signature of the DataFrame() class of pandas module (conventionally named pd) is as follows:

import pandas as pd
?pd.DataFrame

And the output (truncated and modified for readability) is as follows:

Init signature: pd.DataFrame(data=None, index=None, columns=None, dtype=None, copy=False)
Docstring: Two-dimensional size-mutable, potentially heterogeneous tabular data
structure with labeled axes (rows and columns). Arithmetic operations align on both row and column labels. Can be thought of as a dict-like container for Series objects. The primary pandas data structure
Parameters
(a)data : numpy ndarray (structured or homogeneous), dict, or DataFrame.     Dict can contain Series, arrays, constants, or list-like objects
(b)index : Index or array-like. Index to use for resulting frame. Will default to np.arange(n) if no indexing information part of input data and no index provided
(c)columns : Index or array-like. Column labels to use for resulting frame. Will default to np.arange(n) if no column labels are provided
(d)dtype : dtype, default None. Data type to force, otherwise infer
(e)copy : boolean, default False. Copy data from inputs. Only affects DataFrame / 2d ndarray input

Table 20.1: Some data about four planets
In the book the following table for 4 planets is given.

Planet Mass $10^{24} kg$ Diameter (km) Length of day (Hours) Distance from Sun($ 10^6$ km)
Mercury .330 4879 4222.6 57.9
Venus 4.87 12110 2802.0 108.2
Earth 5.97 12756 24.0 149.6
Mars 0.642 6792 24.7 227.9

The code which creates a DataFrame object for this table is as follows:-
This script is available on page 517 of the book

In [2]:
import numpy as np
import pandas as pd
# my_data is a list of lists
# Each inner list represents one row
my_data = [['Mercury', 0.330, 4879, 4222.6, 57.9],
           ['Venus', 4.87, 12104, 2802.0, 108.2],
           ['Earth', 5.97, 12756, 24.0, 149.6],
           ['Mars', 0.642, 6792, 24.7, 227.9]]
df1 = pd.DataFrame(data = my_data)
print(df1)
         0      1      2       3      4
0  Mercury  0.330   4879  4222.6   57.9
1    Venus  4.870  12104  2802.0  108.2
2    Earth  5.970  12756    24.0  149.6
3     Mars  0.642   6792    24.7  227.9

You can modify the above script as follows:

  • Make the names of planets as index. So remove the names of planets from the list of lists.
  • Make a list of names of names of planets. Use this list as index to the DataFrame object.
  • Make a list of headers for each column and use this list for columns.
    The modified script is as follows:
    This script is available on page 518 of the book
In [3]:
import numpy as np
import pandas as pd
# my_data is a list of lists
# Each inner list represents one row
my_data = [[0.330, 4879, 4222.6, 57.9],
           [4.87, 12104, 2802.0, 108.2],
           [5.97, 12756, 24.0, 149.6],
           [0.642, 6792, 24.7, 227.9]]
# Give data for index
my_idx = ['Mercury', 'Venus', 'Earth', 'Mars']
# Give data for columns
my_col = ['Mass', 'Dia', 'Day_len', 'Dist_sun']

df1 = pd.DataFrame(data = my_data, index = my_idx, columns = my_col)
print(df1)
          Mass    Dia  Day_len  Dist_sun
Mercury  0.330   4879   4222.6      57.9
Venus    4.870  12104   2802.0     108.2
Earth    5.970  12756     24.0     149.6
Mars     0.642   6792     24.7     227.9

You can always select and print a particular row, i.e., index or column of a DataFrame object as follows:
This script is available on page 518 of the book

In [4]:
#print column Mass
print(df1['Mass'])
# Print row Venus
print(df1.loc['Venus'])
Mercury    0.330
Venus      4.870
Earth      5.970
Mars       0.642
Name: Mass, dtype: float64
Mass            4.87
Dia         12104.00
Day_len      2802.00
Dist_sun      108.20
Name: Venus, dtype: float64

You can test for data in a particular column, row wise using Boolean selection. If you add a line of code as follows, you get:
This script is available on page 519 of the book

In [5]:
# Test for a condition on a given column of the DataFrame object
print(df1.Mass > 1)
Mercury    False
Venus       True
Earth       True
Mars       False
Name: Mass, dtype: bool

You can also select rows which meet a particular condition in a given column. Suppose you want only those rows (i.e., those planets) whose Mass > 1, then you can write the code as follows:

In [6]:
# Select only those rows where Mass > 1
print(df1[df1.Mass > 1])
       Mass    Dia  Day_len  Dist_sun
Venus  4.87  12104   2802.0     108.2
Earth  5.97  12756     24.0     149.6

20.2.3. Creating a DataFrame from list or from list of lists:
You can easily create a DataFrame object either from a list or from a list of lists (i.e., a nested list). An example script is as follows:
This script is available on page 519 of the book

In [7]:
import pandas as pd
L1 = ['a', 'b', 'c']
L2 = [['Row1', 'a', 1], ['Row2', 'b', 2], ['Row3', 'c', 3]]
# Use list to create a 1D DataFrame object
df1 = pd.DataFrame(data = L1, index = [1, 2, 3], columns = ['Letters'])
print(df1)
# Use list of lists to create 2D DataFrame object
df2 = pd.DataFrame(data = L2, columns = ['RowNumb', 'char', 'number'])
print(df2)
  Letters
1       a
2       b
3       c
  RowNumb char  number
0    Row1    a       1
1    Row2    b       2
2    Row3    c       3

20.2.4. Using the key: value pair of a Dictionary to create a DataFrame object
You can also create a DataFrame by using a dictionary of equal-length list. The key of the dictionary becomes the column names and the value of the dictionary must be a list and each of the list item becomes an entry in the column. This is shown in the following code:
This script is available on page 520 of the book

In [8]:
import pandas as pd
some_data = {'Name': ['Anil', 'Babita', 'Charu', 'Dimple'],
             'Age': [20, 21, 22, 23],
             'Sex': ['M', 'F', 'F', 'F']}
my_df = pd.DataFrame(some_data)
print(my_df)
     Name  Age Sex
0    Anil   20   M
1  Babita   21   F
2   Charu   22   F
3  Dimple   23   F

You can always add a new column to the DataFrame. This can be done by using the following format:-

df_object['new_column_name'] = [list_of_data]

So you can add a new column say Marks to the previous DataFrame. The complete code is shown as follows:
This script is available on page 520 of the book

In [9]:
import pandas as pd
some_data = {'Name': ['Anil', 'Babita', 'Charu', 'Dimple'],
             'Age': [20, 21, 22, 23],
             'Sex': ['M', 'F', 'F', 'F']}
my_df = pd.DataFrame(some_data)
# print(my_df)
my_df['Marks'] = [70, 75, 80, 85]
print(my_df)
     Name  Age Sex  Marks
0    Anil   20   M     70
1  Babita   21   F     75
2   Charu   22   F     80
3  Dimple   23   F     85

You can make any of the columns as index by using the set_index([column_name]) method of the DataFrame. So if you add the following line and then give a print command as shown, then output is as follows:
This script is available on page 521 of the book

In [10]:
my_df = my_df.set_index(['Name'])
print(my_df)
        Age Sex  Marks
Name                  
Anil     20   M     70
Babita   21   F     75
Charu    22   F     80
Dimple   23   F     85

20.2.5. Panel
The signature for pd.Panel() is:

Init signature: pd.Panel(data=None, items=None, major_axis=None, minor_axis=None, copy=False, dtype=None)
Docstring:     
 Represents wide format panel data, stored as 3-dimensional array
 Parameters
 ----------
 data : ndarray (items x major x minor), or dict of DataFrames
 items : Index or array-like axis=0
 major_axis : Index or array-like axis=1
 minor_axis : Index or array-like axis=2
 dtype : dtype, default None. Data type to force, otherwise infer
 copy : boolean, default False. Copy data from inputs. Only affects DataFrame / 2d ndarray input

In the book there is an example of 3 shops selling goods G1, G2, G3 and G4 over a number of years.
The book gives the following figure:-
Figure 20.1: Panel with three axes, one each for (1) Good types (2) Years and (3) the two shops
The following script uses pandas to create this 3D data:
This script is available on page 522 of the book

In [11]:
import pandas as pd
import numpy as np
wp = pd.Panel(np.random.randint(1, 11, (2,6,4)), items=['shop1', 'shop2'],
              major_axis=pd.date_range('1/1/2012', periods=6, freq = 'A'),
              minor_axis=['G1', 'G2', 'G3', 'G4'])
print('For shop1->')
print(wp['shop1'])
print('For shop2->')
print(wp['shop2'])
For shop1->
            G1  G2  G3  G4
2012-12-31   3   2   5   3
2013-12-31  10   8   9   5
2014-12-31   9   3   1   8
2015-12-31   4   5   1   6
2016-12-31   1   9   7   3
2017-12-31   2   3   7   4
For shop2->
            G1  G2  G3  G4
2012-12-31   8   4  10   4
2013-12-31   4   7   5   1
2014-12-31   6   6   1   4
2015-12-31   4   6   5   3
2016-12-31   6   2   6  10
2017-12-31   5  10   8   8
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2862: FutureWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.

  exec(code_obj, self.user_global_ns, self.user_ns)

You can also create a Panel as a dictionary of DataFrames as shown in the following code:

In [12]:
import pandas as pd
import numpy as np
my_data = np.random.randint(1, 11, (2,6,4))
my_items = ['shop1', 'shop2']
my_major_axis = pd.date_range('1/1/2012', periods=6, freq = 'A')
my_minor_axis = ['G1', 'G2', 'G3', 'G4']
wp = pd.Panel(data = my_data, items = my_items, 
              major_axis = my_major_axis,
              minor_axis = my_minor_axis)

print(wp['shop1'])  # You can get data for shop2 also
            G1  G2  G3  G4
2012-12-31  10   1   8   7
2013-12-31  10   8  10   7
2014-12-31   9  10  10   4
2015-12-31   3   6   3   6
2016-12-31   7   7   7   8
2017-12-31   8   3   2   3
C:\ProgramData\Anaconda3\lib\site-packages\IPython\core\interactiveshell.py:2862: FutureWarning: 
Panel is deprecated and will be removed in a future version.
The recommended way to represent these types of 3-dimensional data are with a MultiIndex on a DataFrame, via the Panel.to_frame() method
Alternatively, you can use the xarray package http://xarray.pydata.org/en/stable/.
Pandas provides a `.to_xarray()` method to help automate this conversion.

  exec(code_obj, self.user_global_ns, self.user_ns)

20.3. Using pandas for working on files in various formats
20.3.1. Using pandas to open csv files
The pandas library has a method read_csv(). This method can accept a number of parameters. The signature of the method is as follows:

Signature: pd.read_csv(filepath_or_buffer, sep=',', delimiter=None, header='infer', names=None, index_col=None, usecols=None, squeeze=False, prefix=None, mangle_dupe_cols=True, dtype=None, engine=None, converters=None, true_values=None, false_values=None, skipinitialspace=False, skiprows=None, nrows=None, na_values=None, keep_default_na=True, na_filter=True, verbose=False, skip_blank_lines=True, parse_dates=False, infer_datetime_format=False, keep_date_col=False, date_parser=None, dayfirst=False, iterator=False, chunksize=None, compression='infer', thousands=None, decimal=b'.', lineterminator=None, quotechar='"', quoting=0, escapechar=None, comment=None, encoding=None, dialect=None, tupleize_cols=False, error_bad_lines=True, warn_bad_lines=True, skipfooter=0, skip_footer=0, doublequote=True, delim_whitespace=False, as_recarray=False, compact_ints=False, use_unsigned=False, low_memory=True, buffer_lines=None, memory_map=False, float_precision=None)  
Docstring: Read CSV (comma-separated) file into DataFrame
Returns:- DataFrame or TextParser

The book lists only the important parameters.
The book uses following data stored in a csv file

  • You may first create a csv file (you may create your own csv file).
  • A Notepad++ is used here.
  • The data is as follows:
    Letter, Fruit, Animal, Place A, Apple, Ant, Amritsar B, Berry, Bat, Bangalore C, Cherry, Cat, California
    The name of the file is letters.csv and the absolute path is: C:\Users\DS\Documents\planets.csv
    (Use your file path instead)
    The code on Jupyter is as follows:
    This script is available on page 524 of the book
In [13]:
import pandas as pd
myData = pd.read_csv("C:\Temp\letters.csv", encoding = "ISO-8859-1")
print(myData)
  Letter    Fruit  Animal        Place
0      A    Apple     Ant     Amritsar
1      B    Berry     Bat     Banglore
2      C   Cherry     Cat   California

20.3.2. Using pandas to read html files
You can use the read_html() method of pandas to get a list of dataframes. Consider the following code:
This script is available on page 525 of the book

In [14]:
import pandas as pd

def getData(url):
    try:
        dat = pd.read_html(url)
        print(dat)
        print(type(dat))
    except:
        print("Something went wrong")
#Valid url
u1 = 'https://nssdc.gsfc.nasa.gov/planetary/factsheet/'
#Invalid url
u2 = 'https://xxxxyyyyzzzz'
getData(u1)
getData(u2)
[                               0        1        2      3       4      5   \
0                             NaN  MERCURY    VENUS  EARTH    MOON   MARS   
1                   Mass (1024kg)    0.330     4.87   5.97   0.073  0.642   
2                   Diameter (km)     4879    12104  12756    3475   6792   
3                 Density (kg/m3)     5427     5243   5514    3340   3933   
4                  Gravity (m/s2)      3.7      8.9    9.8     1.6    3.7   
5          Escape Velocity (km/s)      4.3     10.4   11.2     2.4    5.0   
6         Rotation Period (hours)   1407.6  -5832.5   23.9   655.7   24.6   
7           Length of Day (hours)   4222.6   2802.0   24.0   708.7   24.7   
8      Distance from Sun (106 km)     57.9    108.2  149.6  0.384*  227.9   
9             Perihelion (106 km)     46.0    107.5  147.1  0.363*  206.6   
10              Aphelion (106 km)     69.8    108.9  152.1  0.406*  249.2   
11          Orbital Period (days)     88.0    224.7  365.2    27.3  687.0   
12        Orbital Velocity (km/s)     47.4     35.0   29.8     1.0   24.1   
13  Orbital Inclination (degrees)      7.0      3.4    0.0     5.1    1.9   
14           Orbital Eccentricity    0.205    0.007  0.017   0.055  0.094   
15   Obliquity to Orbit (degrees)    0.034    177.4   23.4     6.7   25.2   
16           Mean Temperature (C)      167      464     15     -20    -65   
17        Surface Pressure (bars)        0       92      1       0   0.01   
18                Number of Moons        0        0      1       0      2   
19                   Ring System?       No       No     No      No     No   
20         Global Magnetic Field?      Yes       No    Yes      No     No   
21                            NaN  MERCURY    VENUS  EARTH    MOON   MARS   

          6         7         8         9        10  
0    JUPITER    SATURN    URANUS   NEPTUNE    PLUTO  
1       1898       568      86.8       102   0.0146  
2     142984    120536     51118     49528     2370  
3       1326       687      1271      1638     2095  
4       23.1       9.0       8.7      11.0      0.7  
5       59.5      35.5      21.3      23.5      1.3  
6        9.9      10.7     -17.2      16.1   -153.3  
7        9.9      10.7      17.2      16.1    153.3  
8      778.6    1433.5    2872.5    4495.1   5906.4  
9      740.5    1352.6    2741.3    4444.5   4436.8  
10     816.6    1514.5    3003.6    4545.7   7375.9  
11      4331     10747     30589     59800    90560  
12      13.1       9.7       6.8       5.4      4.7  
13       1.3       2.5       0.8       1.8     17.2  
14     0.049     0.057     0.046     0.011    0.244  
15       3.1      26.7      97.8      28.3    122.5  
16      -110      -140      -195      -200     -225  
17  Unknown*  Unknown*  Unknown*  Unknown*  0.00001  
18        79        62        27        14        5  
19       Yes       Yes       Yes       Yes       No  
20       Yes       Yes       Yes       Yes  Unknown  
21   JUPITER    SATURN    URANUS   NEPTUNE    PLUTO  ]
<class 'list'>
Something went wrong

20.3.3. Reading/Writing to JSON files
In the following script, a JSON object from a DataFrame object is created. For this you may use a to_json(‘path’) method, specifying the path to the file where the json object is to be saved.
The following code shows this:-
This script is available on page 526 of the book

In [15]:
import pandas as pd
import json
# Create a pandas dataframe from the planet data used earlier.
df = pd.DataFrame([[0.330, 4879, 4222.6, 57.9],
                   [4.87, 12104, 2802.0, 108.2],
                   [5.97, 12756, 24.0, 149.6],
                   [0.642, 6792, 24.7, 227.9]],
                  index = ['Mercury', 'Venus', 'Earth', 'Mars'],
                   columns = ['Mass', 'Dia', 'Day_len', 'Dist_sun'])
#Save the dataframe as a JSON object to file testJ.json
df.to_json(r'C:\Temp\testJ.json')
# You can open the testJ.json file and load data to a JSON object called jData
with open(r'C:\Temp\testJ.json', 'r') as jFile:
    jData = json.load(jFile)
print(jData)
print('Convert json data into key:value pair')
for key, val in jData.items():
    print(str(key) + ':' + str(val))
{'Mass': {'Mercury': 0.33, 'Venus': 4.87, 'Earth': 5.97, 'Mars': 0.642}, 'Dia': {'Mercury': 4879, 'Venus': 12104, 'Earth': 12756, 'Mars': 6792}, 'Day_len': {'Mercury': 4222.6, 'Venus': 2802.0, 'Earth': 24.0, 'Mars': 24.7}, 'Dist_sun': {'Mercury': 57.9, 'Venus': 108.2, 'Earth': 149.6, 'Mars': 227.9}}
Convert json data into key:value pair
Mass:{'Mercury': 0.33, 'Venus': 4.87, 'Earth': 5.97, 'Mars': 0.642}
Dia:{'Mercury': 4879, 'Venus': 12104, 'Earth': 12756, 'Mars': 6792}
Day_len:{'Mercury': 4222.6, 'Venus': 2802.0, 'Earth': 24.0, 'Mars': 24.7}
Dist_sun:{'Mercury': 57.9, 'Venus': 108.2, 'Earth': 149.6, 'Mars': 227.9}

Exercise
This topic is given on page 528 of the book
a. The following script produces a DataFrame object consisting of 5 rows and 4 columns and containing random integers between 0 and 10:

In [16]:
import numpy as np
import pandas as pd
# Create a list of lists with dimension 5 x 4 ie 5 lists each with 4 items
my_data = np.random.randint(1, 11, (5, 4))
# The index ie rows are labelled 'A', 'B', ....
my_index = ['A', 'B', 'C', 'D', 'E']
# The columns are numbered 'col1', 'col2', ....
my_col = ['col1', 'col2', 'col3', 'col4']
df1 = pd.DataFrame(data = my_data, index = my_index, columns = my_col )
print(df1)
   col1  col2  col3  col4
A     3     7     9     1
B    10     1     1     4
C     6     3     9     4
D     1    10     7     8
E     1     7    10     9

Beyond text book
This topic is given on page 528 of the book
1. Using pandas to create a pivot table
(For detailed explanation, see the book)
The book uses the following table to explain how a pivot table can be created from an excel sheet.

Shop Item Sale
0 shop1 item1 90
1 shop2 item2 100
2 shop3 item3 50
3 shop4 item1 80
4 shop1 item2 70
5 shop2 item1 100
6 shop3 item3 200
7 shop1 item1 200

Suppose you want to know how much worth of each items were sold by each shop? To answer this question, you need to have the data in a format such that each shop forms a row, each item forms a column and the sum of the sale forms the entry. Then the data will look like as follows:

Item1 Item2 Item3
shop1 290 70 NaN
shop2 100 100 NaN
shop3 NaN NaN 250
shop4 80 NaN NaN

pandas provides a method pivot_table() to create a pivot table from a DataFrame object. The signature of the method is:

pandas.pivot_table(data, values=None, index=None, columns=None, aggfunc='mean', fill_value=None, margins=False, dropna=True, margins_name='All')

A script which creates a DataFrame to represent the above table and to create a pivot table is given as follows:
This script is available on page 530 of the book

In [17]:
import numpy as np
import pandas as pd
# Rows of the DataFrame
r1 = ['shop1', 'item1', 90]
r2 = ['shop2', 'item2', 100]
r3 = ['shop3', 'item3', 50]
r4 = ['shop4', 'item1', 80]
r5 = ['shop1', 'item2', 70]
r6 = ['shop2', 'item1', 100]
r7 = ['shop3', 'item3', 200]
r8 = ['shop1', 'item1', 200]
# DataFrame as a list of lists
sale_data = [r1, r2, r3, r4, r5, r6, r7, r8]
sale_df = pd.DataFrame(sale_data, columns = ['shop', 'item', 'sale'])
print(sale_df)
pv = sale_df.pivot_table(index = 'shop', columns = 'item', 
                         values = 'sale', aggfunc = np.sum)
print('pivot table->')
print(pv)
    shop   item  sale
0  shop1  item1    90
1  shop2  item2   100
2  shop3  item3    50
3  shop4  item1    80
4  shop1  item2    70
5  shop2  item1   100
6  shop3  item3   200
7  shop1  item1   200
pivot table->
item   item1  item2  item3
shop                      
shop1  290.0   70.0    NaN
shop2  100.0  100.0    NaN
shop3    NaN    NaN  250.0
shop4   80.0    NaN    NaN

Beyond text book
This topic is given on pages 530- 536 of the book
2. Using pandas to read/write Excel files
For this exercise, an Excel file named test.xlsx has been created. You can open this file with pandas as shown in the following code:
(Use your file path instead)
This script is available on page 531 of the book

In [18]:
import pandas as pd
myData = pd.read_excel(r"C:\Temp\test.xlsx")
print(myData)
  Unnamed: 0   Mass    Dia  Day_len  Dist_sun
0    Mercury  0.330   4879   4222.6      57.9
1      Venus  4.870  12104   2802.0     108.2
2      Earth  5.970  12756     24.0     149.6
3       Mars  0.642   6792     24.7     227.9

For this exercise, a csv file called letters.csv has been created in Notepad++ (you can use some other editor). The screenshot of this file is shown in Figure 20.8 of the book.
Now you can do some manipulations with this csv data to show the capabilities of Excel methods. The script given below, does the following:

  • First it imports data from a csv file into a DataFrame.
  • Then it changes the index, i.e., the name of the rows of the DataFrame to the column which has Letter as its heading.
  • Then it adds a new row, i.e., a row with index D.

This script is available on page 532 of the book

In [19]:
import pandas as pd
myData = pd.read_csv("C:\Temp\letters.csv", encoding = "ISO-8859-1")

# Convert the column 'letters' into index
myData.set_index('Letter', inplace=True)
#Add a new row to the dataframe. Index of new row is 'D'
myData.loc['D']= ['Dates', 'Duck', 'Delhi']
#Show that the new row has been added to the dataframe
print(myData)

# Create a pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter('C:\Temp\Letters_new.xlsx', engine='xlsxwriter')

# Convert the dataframe to an XlsxWriter Excel object.
myData.to_excel(writer, sheet_name='SheetA')

# Close the pandas Excel writer and output the Excel file.
writer.save()
          Fruit  Animal        Place
Letter                              
A         Apple     Ant     Amritsar
B         Berry     Bat     Banglore
C        Cherry     Cat   California
D         Dates    Duck        Delhi

To use xlswriter with pandas, you need to import it. The xlswriter module provides a Workbook class and you need to create an instance of this class giving the path to the xlsx file as a parameter to this class. Note that xlswriter cannot be used to open/ read or modify existing Excel xlsx files.
This script is available on page 533 of the book

In [20]:
import pandas as pd

# Create a pandas dataframe from the planet data used earlier.
df = pd.DataFrame([[0.330, 4879, 4222.6, 57.9],
                   [4.87, 12104, 2802.0, 108.2],
                   [5.97, 12756, 24.0, 149.6],
                   [0.642, 6792, 24.7, 227.9]],
                  index = ['Mercury', 'Venus', 'Earth', 'Mars'],
                   columns = ['Mass', 'Dia', 'Day_len', 'Dist_sun'])

# Create a pandas Excel writer using XlsxWriter as the engine.
writer = pd.ExcelWriter(r'C:\Temp\test.xlsx', engine='xlsxwriter')

# Convert the dataframe to an XlsxWriter Excel object.
df.to_excel(writer, sheet_name='Sheet1')

# Close the pandas Excel writer and output the Excel file.
writer.save()

You may now use openpyxl. It is a Python library for reading and writing Excel files.
This script is available on page 534 of the book

In [21]:
from openpyxl import Workbook
#Create an instance of Workbook class
wb = Workbook()
# Get the active worksheet
ws1 = wb.active
#Create a new worksheet
ws2 = wb.create_sheet()
# Access cell A1
cA1 = ws1['A1']
#Assign a value to cell A1
cA1.value = 'Hello World'
#Check value of cell A1
print(cA1.value)
#You can get row and column of cell also
print('row->', cA1.row, 'column->', cA1.column)
#Save the workbook
wb.save(r'C:\Temp\test3.xlsx')
Hello World
row-> 1 column-> A

The following script creates a Workbook object from the openpyxl module and then uses this Python module to write to the Workbook object and then read it into a DataFrame
This script is available on page 534 of the book

In [22]:
import pandas as pd
from openpyxl import Workbook
#Create an instance of Workbook class
wb = Workbook()
# Get the active worksheet
ws1 = wb.active

#The 2 for loops will put cell address in each cell as its value
for cObj in ws1['A1': 'D5']:
    for c in cObj:
        c.value = c.coordinate

wb.save(r'C:\Temp\test4.xlsx')
# You can create a dataframe from the contents of a worksheet
df = pd.DataFrame(ws1.values)
#Output of print() confirms dataframe has been created
print(df)
    0   1   2   3
0  A1  B1  C1  D1
1  A2  B2  C2  D2
2  A3  B3  C3  D3
3  A4  B4  C4  D4
4  A5  B5  C5  D5

The following script plots the Dist_sun of the planets. This data is in column 5 of the Excel table. Script is as follows:
This script is available on page 536 of the book

In [23]:
import pandas as pd
from openpyxl import Workbook
from openpyxl import load_workbook
from openpyxl.chart import Reference, Series, LineChart
#Load an Excel file from memory
wb = load_workbook(r'C:\Temp\test.xlsx')
ws = wb.active
# Create a reference to 5th column which has distance from sun data
dval = Reference(ws, min_col=5, min_row=1, max_col=5, max_row=5)

s1 = Series(dval,title="Distance from Sun", title_from_data=True)

chart = LineChart()

chart.append(s1)
ws.add_chart(chart, 'A7')
wb.save(r'C:\Temp\test6.xlsx')